package com.example.rbacmanage.service.impl;

import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import com.example.rbacmanage.common.Constant;
import com.example.rbacmanage.common.enums.CaptchaTypeEnums;
import com.example.rbacmanage.property.CaptchaProperty;
import com.example.rbacmanage.service.SysCaptchaService;
import com.example.rbacmanage.vo.CaptchaResult;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class SysCaptchaServiceImpl implements SysCaptchaService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CaptchaProperty captchaProperty;
    @Autowired
    private  CodeGenerator codeGenerator;
    @Autowired
    private  Font captchaFont;

    @Override
    public boolean validate(String uuid, String code) {
        String redisCode = (String) redisTemplate.opsForValue().get(Constant.CAPTCHA_CODE+uuid);
        if (redisCode == null) {
            return false;
        }else{
            boolean redisCodeVerify = codeGenerator.verify(redisCode, code);
            redisTemplate.delete(Constant.CAPTCHA_CODE+uuid);
            return redisCodeVerify;
        }
    }

    @Override
    public CaptchaResult getCaptcha() {
        String captchaType = captchaProperty.getType();
        int width = captchaProperty.getWidth();
        AbstractCaptcha captcha = getAbstractCaptcha(captchaType,width);
        captcha.setGenerator(codeGenerator);
        captcha.setTextAlpha(captchaProperty.getTextAlpha());
        captcha.setFont(captchaFont);
        String code = captcha.getCode();
        String imageBase64Data = captcha.getImageBase64Data();
        String uuid = IdUtil.fastSimpleUUID();
        Long expireSeconds = captchaProperty.getExpireSeconds();
        redisTemplate.opsForValue().set(Constant.CAPTCHA_CODE+uuid,code,expireSeconds, TimeUnit.SECONDS);
        return CaptchaResult.builder().img(imageBase64Data).uuid(uuid).build();
    }

    private AbstractCaptcha getAbstractCaptcha(String captchaType,int width){
        int height = captchaProperty.getHeight();
        int interfereCount = captchaProperty.getInterfereCount();
        int codeLength = captchaProperty.getCode().getLength();
        AbstractCaptcha captcha;
        if (CaptchaTypeEnums.CIRCLE.name().equalsIgnoreCase(captchaType)){
            captcha = CaptchaUtil.createCircleCaptcha(width,height,codeLength,interfereCount);
        }else if (CaptchaTypeEnums.GIF.name().equalsIgnoreCase(captchaType)){
            captcha=CaptchaUtil.createGifCaptcha(width,height,codeLength);
        }else if (CaptchaTypeEnums.LINE.name().equalsIgnoreCase(captchaType)){
            captcha = CaptchaUtil.createShearCaptcha(width,height,codeLength,interfereCount);
        }else if (CaptchaTypeEnums.SHEAR.name().equalsIgnoreCase(captchaType)){
            captcha=CaptchaUtil.createShearCaptcha(width,height,codeLength,interfereCount);
        }else{
            throw new IllegalArgumentException("Invalid captcha type:"+captchaType);
        }
        return captcha;
    }
}
